<?php
/**
 * Misc Functions
 *
 * @version $Id: functions.php 9 2008-06-30 06:59:37Z jacobsantos $
 */
/**
 * Upload File was not able to be moved.
 *
 * @since 1.0
 */
class UploadNotMovedException extends Exception { }

/**
 * File was not uploaded.
 *
 * @since 1.0
 */
class IsNotUploadedFileException extends Exception { }

/**
 * Move the uploaded file.
 * 
 * Encapsulate common functionality, so that we don't have it adhoc sprung in the code.
 * Places the ugly code away from the main flow.
 *
 * @since 1.0
 *
 * @return string The path to the uploaded WordPress Zip File.
 */
function move_wordpress_zip()
{
	if( is_uploaded_file($_FILES['wordpress']['tmp_name']) ) {
		$wordpress = WP_VERSION_PATH.'/upload/'.basename($_FILES['wordpress']['name']);
		$isMoved = move_uploaded_file( $_FILES['wordpress']['tmp_name'], $wordpress );
		
		if( !$isMoved )
			throw new UploadNotMovedException();
	} else {
		throw new IsNotUploadedFileException();
	}
	
	return $wordpress;
}

/**
 * {@internal Missing Short Description}}
 *
 * @since 1.0
 *
 * @param unknown_type $name
 * @param unknown_type $type
 */
function write_version_info($name, $type)
{
	static $wp_version;
	global $insertStatement;

	if( is_null($wp_version) ) {
		$wp_version = $_POST['version'];
	}

	add_version_info($type, trim( $name ), $wp_version);
}

/**
 * Opens and runs the parse of the WordPress Zip file.
 *
 * @since 1.0
 *
 * @param string $wordpress Path to the WordPress uploaded file.
 */
function open_wordpress_zip($wordpress)
{
	// WordPress exists in an archive, so we have to open it
	// as an archive and extract the contents.
	// The Zip extension makes this available without having to extract
	// the archive first. Does it transparently.
	$za = new ZipArchive();

	// Open the moved upload file to be processed.
	$za->open($wordpress);
	
	/* For Debugging
	
	$source = $za->getFromName('wordpress/wp-includes/cache.php');
	$stripcomments = strip_comments($source);
	
	$tokens = token_get_all($stripcomments);
	$raw_token_list = build_token_tree($tokens);
	token_tree_parse_tokens($raw_token_list);
	return;
	*/

	// We loop through each of the files and open them to check to see
	// if they are PHP. We keep a white list of the file name in order
	// to do the parsing. We don't want to parse files, which aren't PHP.
	for ($i=0; $i<$za->numFiles;$i++) {

		// Get the info on the file for checking the filename.
		$file = $za->statIndex($i);

		// Get the extension for checking the file extension.
		$extension = substr($file['name'], -3, 3);

		// We want anything that ends with php and some early files
		// ended with inc, which are still php files.
		// Add to the list, if you find out that there are other file
		// extensions that are PHP but don't end in PHP.
		if($extension == 'php' || $extension == 'inc') {
			// Get the source of the file
			$getPHP = $za->getFromIndex($i);

			// Strip all of the comments and extra whitespace.
			$stripcomments = strip_comments($getPHP);

			// Get all of the constants and write them to the database
			get_define_names($stripcomments);

			// Get all of the strict global names and write them to the database.
			// By strict, it means that everything that explicitly says "global ...;"
			// will be written and none of the top level variables which are global
			// will be written.
			// It is a little bit harder to do that, so we won't try it.
			get_strict_global_names($stripcomments);

			// Get all of the rest of the tokens to parse
			$tokens = token_get_all($stripcomments);

			// Parse all of the tokens and return just the classes
			// and functions. Everything else will be parsed using
			// regular expressions.
			$raw_token_list = build_token_tree($tokens);

			// Use the newly parsed classes and functions and write
			// them to the database.
			token_tree_parse_tokens($raw_token_list);
		}
	}

	// PHP will close this, but we are good neighbors, so we will close it instead.
	$za->close();
}